/* 
 * Copyright 2014 Josef Hertl.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package caetus.pkcs11.key;

import sun.security.pkcs11.wrapper.CK_MECHANISM;
import sun.security.pkcs11.wrapper.PKCS11Constants;

/**
 * Represents a cipher from PKCS#11
 *
 * @author Josef Hertl
 */
public enum CipherEnum {

    RC2(true, PKCS11Constants.CKM_RC2_KEY_GEN, PKCS11Constants.CKM_RC2_ECB, PKCS11Constants.CKK_RC2) {
        @Override
        public CK_MECHANISM getCipherMechanismReady() {
            CK_MECHANISM ck_mechanism = new CK_MECHANISM(this.getCipherMechanism(), (long) 256);
            return ck_mechanism;
        }
    },
    AES(true, PKCS11Constants.CKM_AES_KEY_GEN, PKCS11Constants.CKM_AES_ECB, PKCS11Constants.CKK_AES),
    DES3(true, PKCS11Constants.CKM_DES3_KEY_GEN, PKCS11Constants.CKM_DES3_ECB, PKCS11Constants.CKK_DES3),
    RSA(false, PKCS11Constants.CKM_RSA_PKCS_KEY_PAIR_GEN, PKCS11Constants.CKM_RSA_PKCS, PKCS11Constants.CKK_RSA);
    /**
     * True if the cipher is symmetric.
     */
    private final boolean symmetric;
    /**
     * The mechanism used by this cipher to generate keys.
     */
    private final long keyGenerationMechanism;
    private final long cipherMechanism;
    private final long keyType;

    private CipherEnum(boolean symmetric, long keyGenerationMechanism, long cipherMechanism, long keyType) {
        this.symmetric = symmetric;
        this.keyGenerationMechanism = keyGenerationMechanism;
        this.cipherMechanism = cipherMechanism;
        this.keyType = keyType;
    }

    public boolean isSymmetric() {
        return symmetric;
    }

    public long getKeyGenerationMechanism() {
        return keyGenerationMechanism;
    }

    /**
     * @return The pointer to the mechanism of this cipher. It should be mostly
     * used with new CK_MECHANISM() with encryption, wrapping and decryption.
     */
    public long getCipherMechanism() {
        return cipherMechanism;
    }

    /**
     * @return The mechanism for encryption, decryption, wrapping and unwrapping
     * at the ready.
     */
    public CK_MECHANISM getCipherMechanismReady() {
        CK_MECHANISM ck_mechanism = new CK_MECHANISM(this.getCipherMechanism());
        return ck_mechanism;
    }

    /**
     * @return Key type used by this cipher. (i.e. CKK_AES)
     */
    public long getKeyType() {
        return keyType;
    }
}
